From 33f5b65e99034ec5a48cce9824793b43422c8a0a Mon Sep 17 00:00:00 2001 From: robertl Date: Tue, 26 Aug 2003 14:55:27 +0000 Subject: [PATCH] Add Delorme route reading. From Ron Parker. --- gpsbabel/Makefile | 3 +- gpsbabel/saroute.c | 256 +++++++++++++++++++++++++++++++++++++++++++++ gpsbabel/vecs.c | 7 ++ 3 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 gpsbabel/saroute.c diff --git a/gpsbabel/Makefile b/gpsbabel/Makefile index 280230e29..15f435227 100644 --- a/gpsbabel/Makefile +++ b/gpsbabel/Makefile @@ -17,7 +17,8 @@ INSTALL_TARGETDIR=/usr/local/ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o \ gpsutil.o pcx.o cetus.o copilot.o gpspilot.o magnav.o \ psp.o holux.o garmin.o tmpro.o tpg.o \ - xcsv.o gcdb.o tiger.o internal_styles.o easygps.o quovadis.o gpilots.o + xcsv.o gcdb.o tiger.o internal_styles.o easygps.o quovadis.o \ + gpilots.o saroute.o FILTERS=position.o duplicate.o arcdist.o polygon.o diff --git a/gpsbabel/saroute.c b/gpsbabel/saroute.c new file mode 100644 index 000000000..c9e0dc910 --- /dev/null +++ b/gpsbabel/saroute.c @@ -0,0 +1,256 @@ +/* + Read various Delorme routes including anr, rte, and rtd. + + Copyright (C) 2003 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include + +#define MYNAME "saroute" +#include "defs.h" + +FILE *infile; + +unsigned short +ReadShort(FILE * f) +{ + unsigned short result = 0; + + fread(&result, sizeof (result), 1, f); + return le_read16(&result); +} + +unsigned long +ReadLong(FILE * f) +{ + unsigned long result = 0; + + fread(&result, sizeof (result), 1, f); + return le_read32(&result); +} + +unsigned char * +ReadRecord(FILE * f, + unsigned long size) +{ + unsigned char *result = xmalloc(size); + + fread(result, size, 1, f); + return result; +} + +void +Skip(FILE * f, + unsigned long distance) +{ + fseek(f, distance, SEEK_CUR); +} + +static void +rd_init(const char *fname, + const char *args) +{ + infile = fopen(fname, "rb"); + if (infile == NULL) { + fatal(MYNAME ": Cannot open %s for reading\n", fname); + } +} + +static void +rd_deinit(void) +{ + fclose(infile); +} + +static void +my_read(void) +{ + + unsigned short version; + unsigned long count; + unsigned long recsize; + unsigned char *record; + unsigned short stringlen; + struct ll { + long lat; + long lon; + } *latlon; + unsigned short coordcount; + route_head *track_head; + waypoint *wpt_tmp; + + ReadShort(infile); /* magic */ + version = ReadShort(infile); +#if 0 + fprintf(outfile, "# Extracted from Delorme route version %d\n", + version); +#endif + ReadLong(infile); + if (version >= 6) { + ReadLong(infile); + ReadLong(infile); + } + + /* + * end of header + */ + + ReadShort(infile); + recsize = ReadLong(infile); + /* + * the first recsize, oddly, doesn't include the filename string + * but it does include the header. + */ + record = ReadRecord(infile, recsize); + + stringlen = le_read16((unsigned short *)(record + 0x1a)); + Skip(infile, stringlen - 4); + free(record); + + /* + * end of filename record + */ + + /* + * here lie the route description records + */ + count = ReadLong(infile); + while (count) { + ReadShort(infile); + recsize = ReadLong(infile); + if (version < 6) { + double lat; + double lon; + + record = ReadRecord(infile, recsize); + stringlen = le_read16((unsigned short *)(record + 0x10)); +#if 0 + if (stringlen) { + fprintf(outfile, "# %*.*s\n", + stringlen, stringlen, + (char *)(record + 0x12)); + } +#endif + latlon = (struct ll *)(record); + + lat = (0x80000000UL - + le_read32(&latlon->lat)) / (double)(0x800000); + lon = (0x80000000UL - + le_read32(&latlon->lon)) / (double)(0x800000); + + wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1); + wpt_tmp->position.latitude.degrees = lat; + wpt_tmp->position.longitude.degrees = -lon; + route_add_wpt(track_head, wpt_tmp); +#if 0 + fprintf(outfile, "%.9lf\t%.9lf\n", lat, -lon); +#endif + } else { + Skip(infile, recsize); + /* + * two longs of scrap after each record, don't know why + */ + ReadLong(infile); + ReadLong(infile); + } + count--; + } + /* + * end of route desc records + */ + + /* + * unknown record (route params?) lives here + */ + count = ReadLong(infile); + while (count) { + ReadShort(infile); + recsize = ReadLong(infile); + Skip(infile, recsize); + count--; + } + /* + * end of unknown record + */ + + /* + * routing begins here + */ + count = ReadLong(infile); + while (count) { + track_head = route_head_alloc(); + route_add_head(track_head); + ReadShort(infile); + recsize = ReadLong(infile); + record = ReadRecord(infile, recsize); + stringlen = le_read16((unsigned short *)record); +#if 0 + fprintf(outfile, "# %*.*s\n", stringlen, stringlen, + (char *)(record + 2)); +#endif + coordcount = + le_read16((unsigned short *)(record + 2 + stringlen + 0x3c)); + latlon = (struct ll *)(record + 2 + stringlen + 0x3c + 2); + count--; + if (count) { + coordcount--; + } + while (coordcount) { + double lat; + double lon; + + wpt_tmp = xcalloc(sizeof (*wpt_tmp), 1); + + lat = (0x80000000UL - + le_read32(&latlon->lat)) / (double)(0x800000); + lon = (0x80000000UL - + le_read32(&latlon->lon)) / (double)(0x800000); + + wpt_tmp->position.latitude.degrees = lat; + wpt_tmp->position.longitude.degrees = -lon; + route_add_wpt(track_head, wpt_tmp); + + latlon++; + coordcount--; + } + free(record); + } + /* + * end of routing + */ + +} + +static void +wr_init(const char *fname, + const char *args) +{ + fatal(MYNAME ":Not enough information is known about this format to write it.\n"); +} + +ff_vecs_t saroute_vecs = { + rd_init, + wr_init, + rd_deinit, + NULL, + my_read, + NULL, + NULL +}; diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c index 3d7cd943b..155b44649 100644 --- a/gpsbabel/vecs.c +++ b/gpsbabel/vecs.c @@ -52,6 +52,7 @@ extern ff_vecs_t gcdb_vecs; extern ff_vecs_t easygps_vecs; extern ff_vecs_t quovadis_vecs; extern ff_vecs_t gpilots_vecs; +extern ff_vecs_t saroute_vecs; static vecs_t vec_list[] = { @@ -188,6 +189,12 @@ vecs_t vec_list[] = { "GpilotS", NULL }, + { + &saroute_vecs, + "saroute", + "Delorme Street Atlast Route", + ".anr" + }, { NULL, NULL, -- 2.30.2